#pragma once

#include "rpc_statistics.hh"

namespace rpc {

class StubCallStatisticsImpl : public StubCallStatistics {
  ServiceStatistics serviceStatistics_; ///< Service statistics
  std::uint32_t max_queue_size_limit_{
      0}; ///< Maximum size limitation of stub queue item
  std::uint32_t peak_qps_limit_{0}; ///< Maximum QPS limitation
  std::uint32_t qps_{0};            ///< Request count/Sec.
  std::uint32_t peak_qps_{0};       ///< Maximum request count/Sec.
  std::time_t min_cost_{0};         ///< Miniimum method cost(Millionseconds)
  std::time_t max_cost_{0};         ///< Maximum method cost(Millionseconds)
  std::time_t avgCost_{0};          ///< Avg. method cost(Millionseconds)
  std::time_t last_tick_{0};        ///< Last tick when invoking
  std::time_t acum_tick_{0};        ///< Accumulated tick period
  std::uint32_t call_count_{0};     ///< Total call count
  std::uint32_t success_count_{0};  ///< Successful call count

public:
  StubCallStatisticsImpl();
  virtual ~StubCallStatisticsImpl();
  virtual bool checkHealthy(std::uint64_t uuid, std::uint32_t queueSize,
                            std::time_t tick) override;
  virtual const ServiceCallStatistics *
  getServiceCallStatistics(std::uint64_t uuid) const noexcept override;
  virtual const ServiceStatistics *
  getServiceStatistics() const noexcept override;
  virtual const MethodCallStatistics *
  getMethodCallStatistics(std::uint64_t uuid,
                          std::uint32_t methodID) const noexcept override;
  virtual const MethodStatistics *
  getMethodStatistics(std::uint64_t uuid) const noexcept override;

  bool start(std::uint32_t maxQpsLimit, std::uint32_t maxQueueSizeLimit);
  bool stop();
  void addStatistics(std::uint64_t uuid, std::uint32_t methodID,
                     std::time_t begin_tick, std::time_t end_tick,
                     const std::string& method_full_name,
                     bool success);
};

/**
 * Statistics initializer.
 * \param maxQpsLimit Maximum QPS limitation
 * \param maxQueueSizeLimit Maximum queue size of stub call
 * \return true or false
 */
extern bool initializeStatistics(std::uint32_t maxQpsLimit,
                                 std::uint32_t maxQueueSizeLimit);
/**
 * Statistics destroyer.
 */
extern void uninitializeStatistics();

extern StubCallStatisticsImpl *getStatisticImpl();

} // namespace rpc
